﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

/// <summary>
///     元数据的语言、上下文和标签上下文类型区域
/// </summary>
/// <remarks>
///     AreaName lcl ( [language] [, [user-context] [, [label-type] ]] )
/// </remarks>
public class MetadataArealDeclaration : MetadataLabeledObject
{
    private StringLiteral? _labelType;
    private StringLiteral? _language;
    private StringLiteral? _userContext;

    internal MetadataArealDeclaration(SyntaxToken declareKeywordToken, Identifier name, SyntaxNode? parent) :
        base(SyntaxKinds.MetadataAreaName, declareKeywordToken, name, parent)
    {
    }


    /// <summary>
    ///     语言名称
    /// </summary>
    public StringLiteral? Language => _language;


    /// <summary>
    ///     用户上下文类型名
    /// </summary>
    public StringLiteral? UserContext => _userContext;


    /// <summary>
    ///     标签类型名
    /// </summary>
    public StringLiteral? LabelType => _labelType;


    /// <summary>
    ///     更新语言名、用户上下文类型和标签类型
    /// </summary>
    /// <param name="langauge">语言名，应当允许长码和短码</param>
    /// <param name="userContext">用户上下文类型名</param>
    /// <param name="labelType">标签类型名</param>
    public MetadataArealDeclaration Update(StringLiteral? langauge, StringLiteral? userContext,
        StringLiteral? labelType)
    {
        SetChildNullableField(ref _language, StringLiteral.IsDefaultOrEmpty, langauge);
        SetChildNullableField(ref _userContext, StringLiteral.IsDefaultOrEmpty, userContext);
        SetChildNullableField(ref _labelType, StringLiteral.IsDefaultOrEmpty, labelType);
        return this;
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, NameIdentifier, DeclareKeywordToken,
            Language, UserContext, LabelType);
    }
}


public static partial class NodeFactory
{
    public static MetadataArealDeclaration CreateMetadataArealDeclaration(SyntaxNode? parent,
        SyntaxToken declareKeywordToken, Identifier identifierName)
    {
        Debug.Assert(declareKeywordToken.IsNode(SyntaxKinds.LclKeywordToken));
        return new MetadataArealDeclaration(declareKeywordToken, identifierName, parent);
    }
}